﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;
using DeepEarth.Core;
using System.Collections.ObjectModel;
using System.Collections;
using DeepEarth.Map.Core;
using DeepEarth.Toolkit.Geometry.Data;
using DeepEarth.Core.Collections;
using DeepEarth.Core.Utilities;

namespace ExampleApplication.Examples
{
    public partial class ChunkedDataBinding : Page
    {
        public ChunkedDataBinding()
        {
            InitializeComponent();
        }

        // Executes when the user navigates to this page.
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            Bind();
            CreateAllPoints();
            Chunk();
        }


        List<MyPointItem> allPoints = new List<MyPointItem>();
        ObservableCollection<MyPointItem> itemSource = new ObservableCollection<MyPointItem>();

        void Bind()
        {
            this.geoItems.ItemsSource = itemSource;
        }

        void CreateAllPoints()
        {
            
            Random rng = new Random(1);

            for (int i = 0; i < maxItemCount; i++)
            { 
                MyPointItem point = new MyPointItem();

                point.SelectionCommand = new LambdaCommand<object>(OnSelected);

                point.Latitude = rng.NextDouble() * (rng.Next(2) == 1 ? 1 : -1) * 80;
                point.Longitude = rng.NextDouble() * (rng.Next(2) == 1 ? 1 : -1) * 180;

                allPoints.Add(point);
            }

        }

        int maxItemCount = 100;
        int chunkSize = 10;

        void Chunk()
        {
            // This does prevent the UI from completely locking up
            if (awaitingRender)
            {
                return;
            }

            awaitingRender = true;
            CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);

            for (int i = 0; i < chunkSize; i++)
            {
                if (!allPoints.Any())
                {
                    return;
                }

                var point = allPoints[0];
                allPoints.RemoveAt(0);
                itemSource.Add(point);
            }

            System.Threading.ThreadPool.QueueUserWorkItem((s) =>
                {
                    System.Threading.Thread.Sleep(1);
                    Chunk();
                }
            );
        }

        // http://www.scottlogic.co.uk/blog/colin/2010/06/throttling-silverlight-mouse-events-to-keep-the-ui-responsive/
        bool awaitingRender;

        void CompositionTarget_Rendering(object sender, EventArgs e)
        {
            awaitingRender = false;
            CompositionTarget.Rendering -= CompositionTarget_Rendering;
            Chunk();
        }

        #region Selection Handler

        // TODO : Attempt to expose Clustered Items. Flesh out this example.
        void OnSelected(object selectedItem)
        {
            MyPointItem item = (MyPointItem)selectedItem;
            var clusterViewModels = ((UIElementLayer)this.map.BaseDynamicLayer.Children[0]).ClusterViewModels;

            var cvm = clusterViewModels.Where(c => c.Data == item).FirstOrDefault();

            if (cvm != null)
            {
                if (cvm.IsCluster)
                {
                    var childItems = cvm.GetClusteredItems();
                }
            }
        }

        #endregion

    }
}
